package com.lime49.lockcrypt;
import com.lime49.lockcrypt.ui.IconTableModel;
import com.lime49.lockcrypt.ui.AbstractDialog;
import java.io.File;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.filechooser.*;
import javax.swing.table.*;
import java.net.URL;
import java.util.*;

public class FrmWelcomeWizard extends AbstractDialog {
    private JPanel welcomePanel, welcomePages, pnlModeFields, welcomePage1, welcomePage2,welcomePage3;
    private JLabel lblHeader, lblPassword, lblPassword2, lblMode, lblDBHost, lblDBUser, lblDBPass, lblDBName, lblDBLocation;
    private JButton btnPrev, btnNext, btnBrowse;
    private JTextField txtDBLocation, txtDBHost, txtDBUser, txtDBName;
    private JPasswordField txtPassword, txtPassword2, passDBPass;
    private JCheckBox chkDefaultData;
    private JComboBox cDBMode;
    private JTable langTable;
    private JTextPane txtWelcomeText, lblDBmode, lblPopulate;
    private ResourceBundle lang;
    private int curPage;
    private static int FRAMEWIDTH = 530, FRAMEHEIGHT = 540;
    
    /**
    * Creates a wizard to guide the user through setting a language, password and database file
    * @param parent The MainWIndow instance to attach this wizard to
    */
    public FrmWelcomeWizard(FrmMainWindow owner) {
        super(owner, "Setup", true);
        lang = Utils.getLanguage("en_GB");
            this.setMinimumSize(new Dimension(FRAMEWIDTH,FRAMEHEIGHT - 30));
            this.setPreferredSize(new Dimension(FRAMEWIDTH,FRAMEHEIGHT));
        welcomePanel = new JPanel();
            welcomePanel.setLayout(new BorderLayout());
        KeyStroke escapeKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
        Action escapeAction = new AbstractAction() {
            // close the frame when the user presses escape
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        }; 
        this.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escapeKeyStroke, "ESCAPE");
        this.getRootPane().getActionMap().put("ESCAPE", escapeAction);

        int cury;
            this.setContentPane(welcomePanel);
        lblHeader = new JLabel("<html><h1>"+lang.getString("INST_STAGE1")+"</h1></html>");
            lblHeader.setBorder(Constants.EMPTYBORDER);
            lblHeader.setMaximumSize(new Dimension(500,80));
            lblHeader.setBackground(Color.getHSBColor(0.58f, 0.1f, 0.95f));
            welcomePanel.add(lblHeader, BorderLayout.PAGE_START);
        welcomePages = new JPanel(new CardLayout());
            welcomePages.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
            welcomePages.setMaximumSize(new Dimension(welcomePages.getWidth(), welcomePages.getHeight()));
            welcomePanel.add(welcomePages, BorderLayout.CENTER);
        
        JPanel welcomePage0 = new JPanel();
            welcomePage0.setLayout(new BoxLayout(welcomePage0, BoxLayout.PAGE_AXIS));
            welcomePages.add(welcomePage0, "p0");
            JTextPane txtSelectLang = new JTextPane();
                txtSelectLang.setText("Select your language to continue");
                txtSelectLang.setBackground(null);
                txtSelectLang.setEditable(false);
                txtSelectLang.setBorder(null);
                txtSelectLang.setMaximumSize(new Dimension(390,Constants.LANGUAGES.size()*12));
                welcomePage0.add(txtSelectLang);
            welcomePage0.add(Box.createVerticalStrut(10));
                
            int cols = 4;
            IconTableModel langTableModel = new IconTableModel(cols);
            Set abbrevs = Constants.LANGUAGES.keySet();
            Iterator iter = abbrevs.iterator();
            while(iter.hasNext()) {
                langTableModel.add(iter.next());
            }
            langTableModel.complete();
            langTable = new JTable(langTableModel);
            langTable.setTableHeader(null);
            langTable.setShowGrid(false);
            langTable.setRowHeight(70);
            langTable.setFont(Utils.getSafeFont("zh", true));
            langTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            langTable.setCellSelectionEnabled(true);
            langTable.setBackground(null);
            Locale osLocale = Locale.getDefault();
            int[] enLocation = null,
                  nativeLocation = null;
            String specificLocale = osLocale.getLanguage()+"_"+osLocale.getCountry();
            String countryLocale = osLocale.getLanguage();
            if(Constants.LANGUAGES.containsKey(specificLocale)) {
                nativeLocation = langTableModel.getValueLocation(specificLocale);
            } else {
                int numRows = langTableModel.getRowCount(),
                    numCols = langTableModel.getColumnCount();
                for(int row = 0;row<numRows;row++) {
                    for(int col = 0;col<numCols;col++) {
                        Object valAtCell = langTableModel.getValueAt(row,col);
                        if(valAtCell == null)
                            continue;
                        String languageAtCell = valAtCell.toString();
                        if(languageAtCell.substring(0, 2).equals(countryLocale)) {
                            nativeLocation = new int[] {row,col};
                            break;
                        } else if(languageAtCell.equals("en_GB")) {
                            enLocation = new int[] {row,col};
                        }
                    }
                }
                if(nativeLocation == null) {
                    nativeLocation = enLocation;
                }
            }
            langTable.changeSelection(nativeLocation[0], nativeLocation[1], false, false);
            TableCellRenderer ImageRenderer = new LangRenderer();
            for(int i=0;i<cols;i++) {
                TableColumn col = langTable.getColumnModel().getColumn(i);
                col.setCellRenderer(ImageRenderer);
                col.setPreferredWidth(52);
            }
            welcomePage0.add(langTable); 
            welcomePage0.add(Box.createVerticalGlue());
                
        /************ Page 1 ************/
        welcomePage1 = new JPanel();
            welcomePages.add(welcomePage1, "p1");
            welcomePage1.setLayout(new GridBagLayout());
            cury = 0;
            GridBagConstraints c = new GridBagConstraints();
                c.insets = new Insets(2,2,2,2);
            txtWelcomeText = new JTextPane();
                txtWelcomeText.setText(lang.getString("WELCOMETEXT"));
                txtWelcomeText.setBackground(null);
                txtWelcomeText.setEditable(false);
                txtWelcomeText.setBorder(null);
                Utils.setgrid(c,cury,0,2,1,GridBagConstraints.HORIZONTAL, GridBagConstraints.FIRST_LINE_START, 1);
                welcomePage1.add(txtWelcomeText,c);
                cury++;
            Utils.setgrid(c,cury,0,2,1,GridBagConstraints.BOTH,GridBagConstraints.CENTER,1);
                welcomePage1.add(Box.createVerticalStrut(6),c);
                cury++;
            lblPassword = new JLabel(lang.getString("PASSWORD"));
                Utils.setgrid(c,cury,0,1,1,GridBagConstraints.NONE,GridBagConstraints.FIRST_LINE_START,0.2);
                welcomePage1.add(lblPassword,c);
            txtPassword = new JPasswordField(20);
                lblPassword.setLabelFor(txtPassword);
                lblPassword.setDisplayedMnemonic('a');
                Utils.setgrid(c,cury,1,1,1,GridBagConstraints.HORIZONTAL,GridBagConstraints.PAGE_START,1);
                cury++;
                welcomePage1.add(txtPassword,c);
            lblPassword2 = new JLabel(lang.getString("CONFIRMPASSWORD"));
                Utils.setgrid(c,cury,0,1,1,GridBagConstraints.NONE,GridBagConstraints.FIRST_LINE_START,0.2);
                welcomePage1.add(lblPassword2,c);
            txtPassword2 = new JPasswordField(20);
                lblPassword2.setLabelFor(txtPassword2);
                lblPassword2.setDisplayedMnemonic('s');
                Utils.setgrid(c,cury,1,1,1,GridBagConstraints.HORIZONTAL,GridBagConstraints.PAGE_START,1);
                cury++;
                welcomePage1.add(txtPassword2,c);
            c.weighty = 2;
            Utils.setgrid(c,cury,0,2,1,GridBagConstraints.BOTH,GridBagConstraints.CENTER,1);
            welcomePage1.add(Box.createVerticalGlue(),c);

        /************ Page 2 ************/
        welcomePage2 = new JPanel();
            welcomePages.add(welcomePage2, "p2");
            cury = 0;
            c.weighty = 1;
            Utils.setgrid(c,cury,0,2,1,GridBagConstraints.BOTH,GridBagConstraints.CENTER,1);
            welcomePage1.add(Box.createVerticalGlue(),c);
             int fieldWidth = 12;
                welcomePage2.setLayout(new GridBagLayout());
                GridBagConstraints DBModeConstraints = new GridBagConstraints();

                DBModeConstraints.insets = new Insets(2,2,2,2);
                lblDBmode = new JTextPane();
                    lblDBmode.setText(lang.getString("DBMODE_DESC"));
                    lblDBmode.setBackground(null);
                    lblDBmode.setEditable(false);
                    lblDBmode.setBorder(null);
                    Utils.setgrid(DBModeConstraints, cury, 0, 2, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.PAGE_START, 1);
                    welcomePage2.add(lblDBmode, DBModeConstraints);
                    cury++;
                Utils.setgrid(DBModeConstraints,cury,0,2,1,GridBagConstraints.BOTH,GridBagConstraints.CENTER,1);
                    welcomePage2.add(Box.createVerticalStrut(6),DBModeConstraints);
                    cury++;
                lblMode = new JLabel(lang.getString("DBMODE"));
                    Utils.setgrid(DBModeConstraints,cury,0,1,1,GridBagConstraints.NONE,GridBagConstraints.FIRST_LINE_START,0.2);
                    welcomePage2.add(lblMode,DBModeConstraints);
                String[] modes = {lang.getString("TXTFILE"), "MySQL"};
                cDBMode = new JComboBox(modes);
                    lblMode.setLabelFor(cDBMode);
                    lblMode.setDisplayedMnemonic('M');
                    cDBMode.addItemListener(new setDBModeListener());
                    Utils.setgrid(DBModeConstraints,cury,1,1,1,GridBagConstraints.HORIZONTAL,GridBagConstraints.PAGE_START,1);
                    welcomePage2.add(cDBMode,DBModeConstraints);
                    cury++;
                pnlModeFields = new JPanel(new CardLayout());
                    Utils.setgrid(DBModeConstraints,cury,0,3,1,GridBagConstraints.HORIZONTAL,GridBagConstraints.FIRST_LINE_START,1);
                    cury++;
                    DBModeConstraints.insets = new Insets(0,0,0,0);
                    welcomePage2.add(pnlModeFields,DBModeConstraints);
                    JPanel pnlTextFields = new JPanel();
                        pnlModeFields.add(pnlTextFields,"text");
                        pnlTextFields.setLayout(new GridBagLayout());
                        GridBagConstraints DBTxtModeFieldsConstraints = new GridBagConstraints();
                        DBTxtModeFieldsConstraints.insets = new Insets(1,1,1,1);
                        DBTxtModeFieldsConstraints.weighty = 1;
                        pnlModeFields.setAlignmentY(JPanel.TOP_ALIGNMENT);
                        lblDBLocation = new JLabel(lang.getString("DBFILE"));
                            Utils.setgrid(DBTxtModeFieldsConstraints,0,0,1,1,GridBagConstraints.NONE,GridBagConstraints.FIRST_LINE_START,0.4);
                            pnlTextFields.add(lblDBLocation,DBTxtModeFieldsConstraints);
                        txtDBLocation = new JTextField(fieldWidth);
                            lblDBLocation.setLabelFor(txtDBLocation);
                            lblDBLocation.setDisplayedMnemonic('F');
                            txtDBLocation.setText(System.getenv("APPDATA")+"\\LockCrypt\\LockCrypt.lce");
                            Utils.setgrid(DBTxtModeFieldsConstraints,0,1,1,1,GridBagConstraints.HORIZONTAL,GridBagConstraints.PAGE_START,1);
                            pnlTextFields.add(txtDBLocation,DBTxtModeFieldsConstraints);
                        btnBrowse = new JButton(lang.getString("BROWSE"));
                            lblDBLocation.setDisplayedMnemonic('B');
                            Utils.setgrid(DBTxtModeFieldsConstraints,0,2,1,1,GridBagConstraints.HORIZONTAL,GridBagConstraints.FIRST_LINE_END,0.2);
                            pnlTextFields.add(btnBrowse,DBTxtModeFieldsConstraints);
                            btnBrowse.addActionListener(new ActionListener() {
                                public void actionPerformed(ActionEvent e) {
                                    JFileChooser fc = new JFileChooser();
                                        fc.setDialogTitle(lang.getString("DBLOCATION"));
                                        FileNameExtensionFilter extLCDBs = new FileNameExtensionFilter(lang.getString("LOCKCRYPTDATABASE"), "lce");
                                            fc.addChoosableFileFilter(extLCDBs);
                                            fc.setSelectedFile(new File(System.getenv("APPDATA")+"\\LockCrypt\\LockCrypt.lce"));
                                        boolean gotFile = false;
                                        File newFileName = null;
                                        while(!gotFile) {
                                            int ret = fc.showSaveDialog(thisDialog);
                                            if(ret == JFileChooser.APPROVE_OPTION) {
                                                newFileName = fc.getSelectedFile();
                                                gotFile = true;
                                            } else if(ret == JFileChooser.CANCEL_OPTION) {
                                                return;
                                            }
                                        }
                                        try {
                                            txtDBLocation.setText(newFileName.getCanonicalPath());
                                        }catch(Exception ignore) {/**/}
                                }
                            });
                    JPanel pnlSQLFields = new JPanel();
                        pnlModeFields.add(pnlSQLFields,"mysql");
                        pnlSQLFields.setLayout(new GridBagLayout());
                        GridBagConstraints DBSQLModeFieldsConstraints = new GridBagConstraints();
                        DBSQLModeFieldsConstraints.insets = new Insets(1,1,1,1);
                        DBSQLModeFieldsConstraints.weighty = 1;
                        lblDBHost = new JLabel(lang.getString("DBHOST"));
                            Utils.setgrid(DBSQLModeFieldsConstraints,0,0,1,1,GridBagConstraints.NONE,GridBagConstraints.FIRST_LINE_START,0.2);
                            pnlSQLFields.add(lblDBHost,DBSQLModeFieldsConstraints);
                        txtDBHost = new JTextField(fieldWidth);
                            lblDBHost.setLabelFor(txtDBHost);
                            lblDBHost.setDisplayedMnemonic('H');
                            Utils.setgrid(DBSQLModeFieldsConstraints,0,1,1,1,GridBagConstraints.HORIZONTAL,GridBagConstraints.PAGE_START,1);
                            pnlSQLFields.add(txtDBHost,DBSQLModeFieldsConstraints);
                        lblDBUser = new JLabel(lang.getString("DBUSER"));
                            Utils.setgrid(DBSQLModeFieldsConstraints,1,0,1,1,GridBagConstraints.NONE,GridBagConstraints.FIRST_LINE_START,0.2);
                            pnlSQLFields.add(lblDBUser,DBSQLModeFieldsConstraints);
                        txtDBUser = new JTextField(fieldWidth);
                            lblDBUser.setLabelFor(txtDBUser);
                            lblDBUser.setDisplayedMnemonic('U');
                            Utils.setgrid(DBSQLModeFieldsConstraints,1,1,1,1,GridBagConstraints.HORIZONTAL,GridBagConstraints.PAGE_START,1);
                            pnlSQLFields.add(txtDBUser,DBSQLModeFieldsConstraints);
                        lblDBPass = new JLabel(lang.getString("DBPASS"));
                            Utils.setgrid(DBSQLModeFieldsConstraints,2,0,1,1,GridBagConstraints.NONE,GridBagConstraints.FIRST_LINE_START,0.2);
                            pnlSQLFields.add(lblDBPass,DBSQLModeFieldsConstraints);
                        passDBPass = new JPasswordField(fieldWidth);
                            lblDBPass.setLabelFor(passDBPass);
                            lblDBPass.setDisplayedMnemonic('a');
                            Utils.setgrid(DBSQLModeFieldsConstraints,2,1,1,1,GridBagConstraints.HORIZONTAL,GridBagConstraints.PAGE_START,1);
                            pnlSQLFields.add(passDBPass,DBSQLModeFieldsConstraints);
                        lblDBName = new JLabel(lang.getString("DBDATABASE"));
                            Utils.setgrid(DBSQLModeFieldsConstraints,3,0,1,1,GridBagConstraints.NONE,GridBagConstraints.FIRST_LINE_START,0.2);
                            pnlSQLFields.add(lblDBName,DBSQLModeFieldsConstraints);
                        txtDBName = new JTextField(fieldWidth);
                            lblDBName.setLabelFor(txtDBName);
                            lblDBName.setDisplayedMnemonic('D');
                            Utils.setgrid(DBSQLModeFieldsConstraints,3,1,1,1,GridBagConstraints.HORIZONTAL,GridBagConstraints.PAGE_START,1);
                            pnlSQLFields.add(txtDBName,DBSQLModeFieldsConstraints);
            c.weighty = 2;
            Utils.setgrid(DBModeConstraints,cury,0,2,1,GridBagConstraints.BOTH,GridBagConstraints.CENTER,1);
            welcomePage2.add(Box.createVerticalGlue(),DBModeConstraints);
            
        /************ Page 3 ************/
        welcomePage3 = new JPanel();
            welcomePages.add(welcomePage3, "p3");
            welcomePage3.setLayout(new BoxLayout(welcomePage3, BoxLayout.PAGE_AXIS));
            lblPopulate = new JTextPane();
                lblPopulate.setText(lang.getString("DUMMYDATA_DESC"));
                lblPopulate.setBackground(null);
                lblPopulate.setEditable(false);
                lblPopulate.setBorder(null);
                welcomePage3.add(lblPopulate);
            chkDefaultData = new JCheckBox("<HTML>"+lang.getString("DUMMYDATA")+"</HTML>");
                chkDefaultData.setMnemonic('o');
                chkDefaultData.setSelected(true);
                welcomePage3.add(chkDefaultData);
            welcomePage3.add(Box.createVerticalStrut(90));

        JPanel buttonBox = new JPanel();
            buttonBox.setBorder(Constants.EMPTYBORDER);
            buttonBox.setLayout(new BoxLayout(buttonBox, BoxLayout.LINE_AXIS));
            buttonBox.add(Box.createHorizontalGlue());
            btnPrev = new JButton(lang.getString("PREVIOUS"));
                btnPrev.setMnemonic('P');
                btnPrev.addActionListener(new btnPrevListener());
                buttonBox.add(btnPrev);
            buttonBox.add(Box.createHorizontalStrut(10));
            btnNext = new JButton(lang.getString("NEXT"));
                btnNext.setMnemonic('N');
                btnNext.addActionListener(new btnNextListener());
                buttonBox.add(btnNext);
                btnPrev.setMinimumSize(Constants.MINSIZE);
                btnPrev.setPreferredSize(Constants.PREFSIZE);
                btnPrev.setMaximumSize(Constants.MAXSIZE);
                btnNext.setMinimumSize(Constants.MINSIZE);
                btnNext.setPreferredSize(Constants.PREFSIZE);
                btnNext.setMaximumSize(Constants.MAXSIZE);
        welcomePanel.add(buttonBox,BorderLayout.SOUTH);
        
        curPage = 1;
        setButtons();
        this.getRootPane().setDefaultButton(btnNext);
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.pack();
        this.setLocationRelativeTo(owner);
        this.setVisible(true);
        txtPassword.requestFocusInWindow();
    }
    
    /**
    * Refreshes the buttons and labels to the currently selected language
    */
    private void updateLang() {
        /************ Page 1 ************/
        lblPassword.setText(lang.getString("PASSWORD"));
        lblPassword2.setText(lang.getString("CONFIRMPASSWORD"));
            
        /************ Page 2 ************/
        txtWelcomeText.setText(lang.getString("WELCOMETEXT"));
        lblDBmode.setText(lang.getString("DBMODE_DESC"));
        lblMode.setText(lang.getString("DBMODE"));
        lblDBLocation.setText(lang.getString("DBFILE"));
        btnBrowse.setText(lang.getString("BROWSE"));
        lblDBHost.setText(lang.getString("DBHOST"));
        lblDBUser.setText(lang.getString("DBUSER"));
        lblDBPass.setText(lang.getString("DBPASS"));
        lblDBName.setText(lang.getString("DBDATABASE"));

        /************ Page 3 ************/
        chkDefaultData.setText("<HTML>"+lang.getString("DUMMYDATA")+"</HTML>");
        lblPopulate.setText(lang.getString("DUMMYDATA_DESC"));
        
        /************ Nav buttons ************/
        btnNext.setText(lang.getString("NEXT"));
        btnPrev.setText(lang.getString("PREVIOUS"));
        this.pack();
        this.repaint();
    }
    
    /**
    * Sets the heading text and buttons for the current page, disabling the previous button for the first page
    */
    private void setButtons() {
        updateLang();
        switch(curPage) {
            case 1:
                btnPrev.setEnabled(false);
                break;
            case 2:
                btnPrev.setEnabled(true);
                lblHeader.setText("<html><h1>"+lang.getString("INST_STAGE1")+"</h1></html>");
                txtPassword.requestFocusInWindow();
                break;
            case 3:
                lblHeader.setText("<html><h1>"+lang.getString("INST_STAGE2")+"</h1></html>");
                btnNext.setText(lang.getString("NEXT"));
                cDBMode.requestFocusInWindow();
                break;
            case 4:
                lblHeader.setText("<html><h1>"+lang.getString("INST_STAGE3")+"</h1></html>");
                btnNext.setText(lang.getString("FINISH"));
                break;
        }
    }
    
    /**
    * Reads the settings the user has entered
    * @return An array of strings containing the users choices for the wizard
    */
    public String[] getSetup() {
        return new String[] {
            new String(txtPassword.getPassword()),   // 0
            cDBMode.getSelectedItem().toString(),    // 1
            txtDBLocation.getText(),                 // 2
            txtDBHost.getText(),                     // 3
            txtDBUser.getText(),                     // 4
            new String(passDBPass.getPassword()),    // 5
            txtDBName.getText(),                     // 6
            chkDefaultData.isSelected() ? "1" : "0",  // 7
            (String)langTable.getValueAt(langTable.getSelectedRow(), langTable.getSelectedColumn())
        };
    }
    
    /**
    * Moves to the previous page of the CardLayout
    */
    class btnPrevListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
                curPage--;
                CardLayout pages = (CardLayout)welcomePages.getLayout();
                pages.previous(welcomePages);
                setButtons();
        }
    }
    
    /**
    * Moves to the next page of the CardLayout.
    * On page 1, refreshes the language strings on labels and headings.
    * On page 2, checks that the password is not blank and that both passwords match
    * On page 3, checks that a location has been entered for text mode, or MySQL credentials have been entered if using MySQL
    * On page 4, sets the isReady flag to true, signalling that the user is finished entering data
    */
    class btnNextListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            boolean error = false;
            switch(curPage) {
                case 1:
                    String langCode = (String)langTable.getValueAt(langTable.getSelectedRow(), langTable.getSelectedColumn());
                    lang = Utils.getLanguage(langCode);
                    updateLang();
                    break;
                case 2:
                    String pass1 = new String(txtPassword.getPassword());
                    String pass2 = new String(txtPassword2.getPassword());
                    if(pass1.equals(pass2)) {
                        if(pass1.isEmpty()) {
                            if(JOptionPane.showConfirmDialog(thisDialog, lang.getString("ERR_PASSBLANK_DESC"), lang.getString("ERR_PASSBLANK"), JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) {
                                error = true;
                            }
                        }
                    } else {
                        JOptionPane.showMessageDialog(thisDialog, lang.getString("ERR_PASSNOMATCH_DESC"), lang.getString("ERR_PASSNOMATCH"), JOptionPane.ERROR_MESSAGE);
                        error = true;
                    }
                    break;
                case 3:
                    if(cDBMode.getSelectedItem().toString().equals(lang.getString("TXTFILE")) && txtDBLocation.getText().isEmpty()) {
                        JOptionPane.showMessageDialog(thisDialog, lang.getString("ERR_DBLOCBLANK"), lang.getString("ERROR"), JOptionPane.ERROR_MESSAGE);
                        error = true;
                    }
                    break;
                case 4:
                    result = JOptionPane.OK_OPTION;
                    thisDialog.setVisible(false);
                    break;
            }
            if(!error && curPage != 4) {
                curPage++;
                CardLayout pages = (CardLayout)welcomePages.getLayout();
                pages.next(welcomePages);
                setButtons();
            }
        }
    }
    
    /**
    * Switches between cards for entering a database location (text mode) or MySQL credentials
    */
    class setDBModeListener implements ItemListener {
        // Switches cards when the value of JComboBox 'cDBMode' changes
        public void itemStateChanged(ItemEvent e) {
            CardLayout modeCards = (CardLayout)(pnlModeFields.getLayout());
            if(cDBMode.getSelectedItem().equals(lang.getString("TXTFILE"))) {
                modeCards.show(pnlModeFields, "text");
            } else if(cDBMode.getSelectedItem().equals("MySQL")) {
                modeCards.show(pnlModeFields, "mysql");
            }
        }
    }
    
    /**
    * Renders a string (en, de, cz etc) as a flag from the /images/flags/ directory
    */
    class LangRenderer extends DefaultTableCellRenderer implements TableCellRenderer {
        @Override
        public Component getTableCellRendererComponent(
                        JTable table, Object img,
                        boolean isSelected, boolean hasFocus,
                        int row, int column) {
            if(img == null || img.equals("")) {
                return null;
            } else {
                try {
                    this.setHorizontalAlignment(SwingConstants.CENTER);
                    this.setVerticalAlignment(SwingConstants.CENTER);
                    this.setVerticalTextPosition(SwingConstants.BOTTOM);
                    this.setHorizontalTextPosition(SwingConstants.CENTER);
                    URL iconURL = this.getClass().getResource("images/flags/"+img+".png");
                    ImageIcon imgIcon = new ImageIcon(Toolkit.getDefaultToolkit().getImage(iconURL));
                    this.setIcon(imgIcon);
                    this.setText(Constants.LANGUAGES.get(img));
                    if(isSelected) {
                        this.setBackground(Color.getHSBColor(0.58f, 0.2f, 1f));
                        this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
                    } else {
                        this.setBorder(null);
                        this.setBackground(null); //PlasticLookAndFeel.getControl());
                    }
                } catch(Exception ignore) {}
            }
            return this;
        }
    }
}
